/*
 * Anything: A flexible and easy to use data structure that combines the 
 * characteristics of a list and a hashmap into one data structure.
 * 
 * Based on a paper by Peter Sommerlad and Marcel Rueedi on 
 * 'Do-it-yourself reflection' entered at EuroPLOP 1998.
 * 
 * This library was written completely from scratch and is based only 
 * in spirit on the original Java Anything implementation written by 
 * Andre Weinand/Marcel Rueedi in 1997/99 and enhanced by Stefan Tramm 
 * in 2006.
 * 
 * Copyright (c) 2008 Thomas Marti and others. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package any.impl.util;

import java.io.Serializable;
import java.util.Map;

import any.Any;
import any.impl.Anything;

public class MapEntry<K, V> implements Map.Entry<K, V>, Serializable {

	private static final long serialVersionUID = -1384061749694619811L;

	private K key;

	private V value;
	
	public MapEntry(K key, V value) {
		this.key = key;
		this.value = value;
	}

	public K getKey() {
		return key;
	}

	public void setKey(K key) {
		this.key = key;
	}

	public V getValue() {
		return value;
	}

	public V setValue(V value) {
		V oldValue = this.value;
		this.value = value;
		return oldValue;
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof Map.Entry<?, ?>)) {
			return false;			
		}
	    Map.Entry<?, ?> e = (Map.Entry<?, ?>)obj;
	    return Utils.equals(key, e.getKey()) && Utils.equals(value, e.getValue());
	}

	@Override
	public int hashCode() {
		return (key == null ? 0 : key.hashCode()) ^
		       (value == null ? 0 : value.hashCode());
	}
	
	@Override
	public String toString() {
		return (key != null ? "\'" + key + "\'": "null") + " => " + value;
	}

	@SuppressWarnings("unchecked")
	public static <V, M extends Map.Entry<String, V>> M createMapEntry(String key, V value) {
		return (M) new MapEntry<String, V>(key, value);
	}


	public static MapEntry<String, Any> createAnyEntry(String key, Object value) {
    	MapEntry<String, Any> entry = createAnyEntry(value);
    	if (key != null) {
    		entry.setKey(key);
    	}
    	
    	return entry;
    }

	public static MapEntry<String, Any> createAnyEntry(Object value) {
    	String key = null;
    	Any any = null;
    	if (value instanceof Map.Entry<?, ?>) {
    		Map.Entry<?, ?> entry = (Map.Entry<?, ?>)value;
    		if (entry.getKey() != null) {
    			key = entry.getKey().toString();
    		}
    		any = Anything.getAny(true, entry.getValue());
    	} else {
    		any = Anything.getAny(true, value);
    	}
    
    	return createMapEntry(key, any);
    }
	
}
